#ifndef _Instruction_h
#define _Instruction_h

#include <string>
#include "string.h"
#include "Operande.hpp"

using std::string;

class Instruction{
public:
	char* etiquette;
	int codeInst;
	Operande op1;
	Operande op2;
	Operande op3;
	
	Instruction() {
	};
	
    	Instruction(int c, Operande o1, Operande o2, Operande o3){
    		codeInst = c;
    		etiquette = (char *) "";
    		op1 = o1;
    		op2 = o2;
    		op3 = o3;
    	};
    	
    	Instruction(int c,Operande o1, Operande o2){
    		codeInst = c;
    		etiquette = (char *)"";
    		op1=o1;
    		op2=o2;
        Operande o;
        op3=o;
    	};
    	
    	Instruction(int c,Operande o1) {
    	 	codeInst = c;
    		etiquette = (char *)"";
    		op1=o1;
        Operande o2;
        op2=o2;
        Operande o;
        op3=o;
    	};
      Instruction(int c,char* et) {
        codeInst = c;
    		etiquette =et;
        Operande o;
        op1=o;
    		op2 = o;
    		op3 = o;
      }
    	~Instruction(){
    	};
    	
    	void setEtiquette (char* e) {
    		etiquette = e;
    	};
    	
    	char* getEtiquette() {
    		return(etiquette);
    	};
    	
    	void setOp1(Operande o) {
    		op1 = o;
    	};
    	
    	void setOp2(Operande o) {
    		op2 = o;
    	};
    	
    	void setOp3(Operande o) {
    		op3 = o;
    	};
    	
    	Operande getOp1() {
    		return(op1);
    	};
    	
    	Operande getOp2() {
        
        return(op2);
        
    };
    
    Operande getOp3() {
      return op3;
    	};
    	
    	void afficherInstr() {
    		string affEt="";
    		
    		if(strcmp(etiquette,"") != 0)
    		{
    			affEt += etiquette;
    			if(affEt.size() < 5)
    				affEt += " : \t\t";
    			else
    				affEt += " : \t";
    		}
    		else
    			affEt="\t\t";
    		

    		switch(codeInst)
    		{
    			case 0: cout << affEt << endl; 
    				break;
    			case 1:cout << affEt << op1.getOp() << " := " << op2.getOp() << " + " << op3.getOp() << endl;  
    				break;
    			case 2: cout << affEt << op1.getOp() << " := " << op2.getOp() << " - " << op3.getOp() << endl; 
    				break;
	    		case 3:	cout << affEt << op1.getOp() << " := " << op2.getOp() << " * " << op3.getOp() << endl; 
	    			break;
    			case 4: cout << affEt << op1.getOp() << " := " << op2.getOp() << " / " << op3.getOp() << endl; 
    				break;
    			case 5: cout << affEt << op1.getOp() << " := - " << op2.getOp() << endl; 
    				break;
    			case 6:	cout << affEt << op1.getOp() << " := " << op2.getOp() << " & " << op3.getOp() << endl; 
    				break;
	    		case 7:	cout << affEt << op1.getOp() << " := " << op2.getOp() << " | " << op3.getOp() << endl; 
	    			break;
    			case 8:	cout << affEt << op1.getOp() << " := ! " << op2.getOp() << endl; 
    				break;
    			case 9: cout << affEt << op1.getOp() << " := " << op2.getOp() << endl;
    				break;
    			case 10: cout << affEt << op1.getOp() << " := " << op2.getOp() << " < " << op3.getOp() << endl;
    				break;
    			case 11: cout << affEt << op1.getOp() << " := " << op2.getOp() << " > " << op3.getOp() << endl; 
    				break;
    			case 12: cout << affEt << op1.getOp() << " := " << op2.getOp() << " <= " << op3.getOp() << endl;
    				break;
    			case 13: cout << affEt << op1.getOp() << " := " << op2.getOp() << " >= " << op3.getOp() << endl;
    				break;
    			case 14: cout << affEt << op1.getOp() << " := " << op2.getOp() << " == " << op3.getOp() << endl; 
    				break;
    			case 15: cout << affEt << op1.getOp() << " := " << op2.getOp() << " != " << op3.getOp() << endl;
    				break;
    			case 16: cout << affEt << " aller a " << op1.getOp() << endl;
    				break;
    			case 17: cout << affEt << " si " << op1.getOp() << " aller a " << op2.getOp() << endl;
    				break;
    			case 18: cout << affEt << op1.getOp() << " := " << op2.getOp() << " [ " << op3.getOp() << " ] " << endl; 
    				break;
    			case 19: cout << affEt << op1.getOp() << " [ " << op2.getOp() << " ] " << " := " << op3.getOp() << endl;
    				break;
   			case 20: cout << affEt << op1.getOp() << " = & " << op2.getOp() << endl; 
    				break;
   			case 21: cout << affEt << op1.getOp() << " = * " << op2.getOp() << endl; 
    				break;
   			case 22: cout << affEt << "* " << op1.getOp() << " = " << op2.getOp() << endl; 
    				break;
   			case 23: cout << affEt << "push " << op1.getOp() << endl; 
    				break;
   			case 24: cout << affEt << "push " << op1.getOp() << " [ " << op2.getOp() << " ] " << endl; 
    				break;
			case 25: cout << affEt << "push " << op1.getOp() << " & " << op2.getOp() << endl; 
    				break;
   			case 26: cout << affEt << "push " << op1.getOp() << " * " << op2.getOp() << endl;    	
    				break;
		   	case 27: cout << affEt << "pop " << op1.getOp() << endl; 
    				break;
    			case 28: cout << affEt << "pop " << op1.getOp() << " [ " << op2.getOp() << " ] " << endl; 
    				break;
    			case 29: cout << affEt << "pop " << op1.getOp() << " * " << op2.getOp() << endl; 
    				break;
    			case 30: cout << affEt << "call " << op1.getOp() << endl; 
    				break;
    			case 31: cout << affEt << "return " << endl; 
    				break;
    			case 32: cout << affEt << "return " << op1.getOp() << endl; 
    				break;
    			case 33: cout << affEt << "end " << endl; 
    				break;
    			default: cout << "Erreur: Mauvais code d'instruction" <<endl;
    				break;
    			
        }
    };
    
    
    
    
    
};

#endif
